import { Component, OnInit, Input, Output, EventEmitter, OnChanges, SimpleChanges, ElementRef } from '@angular/core';
import { Headers, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import * as $ from 'jquery';

@Component({
  selector: 'app-jquery-tree',
  template: '<ul class="tree"></ul>',
  styles:[]
})

export class JqueryTreeComponent implements OnInit {

  @Input() id = "id";
  @Input() title = "title";
  @Input() pid = "parentId";
  @Input() children = "children";
  private root = [];
  private el: HTMLElement;

  constructor(ref: ElementRef, private http: Http){
    this.el = ref.nativeElement;
  }

  ngOnInit() {

  }

  public toTree (simpleArray) {
    if(!simpleArray || simpleArray.length<1) return [];

    let treeArray = [];
    let treeObject = {};

    for(let obj of simpleArray) {
      treeObject[obj[this.id]] = obj;
    }

    for(let obj of simpleArray) {
      let parentObj = treeObject[obj[this.pid]];
      if(parentObj) {
        if(!parentObj[this.children]) parentObj[this.children] = [];
        parentObj[this.children].push(obj);
      } else {
        treeArray.push(obj);
      }
    }

    return treeArray;
  }

  public select () {
    return $(this.el).find('li.tree-selected:first').data('tree-data');
  }

  public selects () {
    let selectedArray = [];
    $(this.el).find('li.tree-selected').each((index, ele)=>{
      selectedArray.push($(ele).data('tree-data'));
    });
    return selectedArray;
  }

  public clear (treeData, includeSelf = true) {

    let deleteArray;
    if(treeData == null) {
      deleteArray =this.root;
    } else if(treeData instanceof Array && treeData.length > 0) {
      deleteArray = treeData;
    } else if(treeData instanceof Object) {
      deleteArray = [treeData];
    } else {
      return;
    }

    for (let obj of deleteArray) {
      let deleteDom = $(this.el).find('li').filter((index, ele) => {
        return $(ele).data('tree-data') == obj;
      });

      if(includeSelf) {
        let index = deleteDom.index();
        let parentData = deleteDom.parent().parent().data('tree-data');
        if(parentData) {
          parentData[this.children].splice(index, 1);
        } else {
          this.root.splice(index, 1);
        }
        deleteDom.remove();
      } else {
        obj[this.children] = [];
        deleteDom.children("ul").empty();
      }
    }
  }

  public add (treeData, parentData = null) {
    let childrenArray;
    if(treeData instanceof Array && treeData.length > 0) {
      childrenArray = treeData;
    } else if(treeData instanceof Object) {
      childrenArray = [treeData];
    } else {
      return;
    }

    if(parentData) {

      if(!parentData[this.children]) parentData[this.children] = [];
      parentData[this.children].push.apply(parentData[this.children], childrenArray);
      let parentDom = $(this.el).find('li').filter((index, ele) => {
        return $(ele).data('tree-data') == parentData;
      }).children('ul');
      this.render(childrenArray, parentDom);
    } else {

      this.root.push.apply(this.root, childrenArray);
      let parentDom = $(this.el).children('ul');
      this.render(childrenArray, parentDom);
    }
  }

  private render(childrenData, parentDom) {
    for(let obj of childrenData){
      if(!obj[this.children]) obj[this.children] = [];
      let childDom = $(`
        <li class="tree-branch">
          <i class="icon-caret ace-icon tree-plus"></i>&nbsp;
          <div class="tree-branch-header">
            <span class="tree-branch-name"><span class="tree-label">${obj[this.title]}</span></span>
          </div>
          <ul class='tree-branch-children' style="display: none;"></ul>
        </li>
      `);
      childDom.data('tree-data', obj).appendTo(parentDom);
      childDom.children('i').click((event) => {
        let target = $(event.currentTarget);
        if(target.hasClass('tree-plus')) {
          target.removeClass('tree-plus').addClass('tree-minus');
          target.siblings('ul').slideDown();
        } else {
          target.removeClass('tree-minus').addClass('tree-plus');
          target.siblings('ul').slideUp();
        }
      });
      childDom.children('div').click((event) => {
        let target = $(event.currentTarget).parent();
        if(target.hasClass('tree-selected')) {
          target.removeClass('tree-selected');
        } else {
          target.addClass('tree-selected');
        }
      });
      this.render(obj[this.children], childDom.children('ul'));
    }
  }

}
